﻿using Core.MemCache;
using System.Collections.Generic;

namespace Core
{
    /// <summary>
    /// Memory Cache
    ///
    /// <para>可用于实现黑名单、白名单效果</para>
    /// <para>可用于实现临时的数据缓存效果</para>
    ///
    /// </summary>
    public class MemCacheSystem : Core.Component, IAwake
    {
        private readonly Dictionary<string, Container> dict = new();

        public void Awake()
        {
        }

        public override void Dispose()
        {
            if (IsDisposed) return;

            foreach (var kvp in dict)
            {
                ReferencePool.Recycle(kvp.Value);
            }
            dict.Clear();

            base.Dispose();
        }

        private Container GetItem(string key, bool autoCreate)
        {
            if (dict.TryGetValue(key, out var item1))
            {
                return item1;
            }

            if (autoCreate)
            {
                var item = ReferencePool.Acquire<Container>();
                dict[key] = item;
                return item;
            }

            return null;
        }

        public void Add<T>(string key, T value)
        {
            var container = GetItem(key, true);
            container.Add(value);
        }

        public void Remove<T>(string key, T value)
        {
            var container = GetItem(key, false);
            if (container == null)
            {
                return;
            }

            container.Remove(value);

            if (container.Count == 0)
            {
                ReferencePool.Recycle(container);
                dict.Remove(key);
            }
        }

        public void Set<T>(string key, T value)
        {
            var container = GetItem(key, true);
            container.Set(value);
        }

        public T Get<T>(string key)
        {
            var container = GetItem(key, false);
            if (container == null)
            {
                return default;
            }
            return container.Get<T>();
        }

        public bool Contains<T>(string key, T value)
        {
            var container = GetItem(key, false);
            if (container == null)
            {
                return false;
            }
            return container.Contains(value);
        }

        public bool ContainsExcept<T>(string key, T value)
        {
            var container = GetItem(key, false);
            if (container == null)
            {
                return false;
            }
            return container.ContainsExcept(value);
        }

        public bool Contains(string key)
        {
            var container = GetItem(key, false);
            if (container == null)
            {
                return false;
            }
            return container.Count > 0;
        }
    }
}
